package Model;
import java.util.ArrayList;


public class RegulaFalsi {
	private ArrayList<Double> x0List;
	private ArrayList<Double> x1List;
	private ArrayList<Double> x2List;
	private ArrayList<Double> y0List;
	private ArrayList<Double> y1List;
	private ArrayList<Double> y2List;
	private ArrayList<Double> coefList;
	private ArrayList<Double> powerList;
	private ArrayList<Double> trueXList;
	private ArrayList<Double> trueYList;
	private ArrayList<Double> thresholdList;
	private double x0, x1, x2, y0, y1, y2;
	private int nIteration;
	private double threshold;

	
	public RegulaFalsi() {
		coefList = new ArrayList<Double>();
		powerList = new ArrayList<Double>();
		x0List = new ArrayList<Double>();
		x1List = new ArrayList<Double>();
		x2List = new ArrayList<Double>();
		y0List = new ArrayList<Double>();
		y1List = new ArrayList<Double>();
		y2List = new ArrayList<Double>();
		trueXList = new ArrayList<Double>();
		trueYList = new ArrayList<Double>();
		thresholdList = new ArrayList<Double>(); 
	}
	
	public RegulaFalsi(double x0, double x1, int nIteration, String function, double threshold)
	{
		this.x0 = x0;
		this.x1 = x1;
		this.threshold = threshold;
		this.nIteration = nIteration;
		this.parseFunction(function);
	}

	public void parseFunction(String function){
		String[] temp = function.split(" ");

		
		for(int i = 0; i < temp.length; i+=2)
		{
			coefList.add(Double.parseDouble(temp[i]));
			powerList.add(Double.parseDouble(temp[i+1]));
		}
	}
	
	public double computeY(double x){
		double result = 0;
		for(int i = 0; i < coefList.size(); i++)
			result += coefList.get(i) * Math.pow(x, powerList.get(i));
		
		return result;
	}
	
	public void computeRegulaFalsi(){
		// true value
		double temp = x0-15;
		while(temp <= x1+15)
		{
			trueXList.add(temp);
			trueYList.add(computeY(temp));
			temp++;
		}
		
		// regula falsi
		double currentthreshold = Math.abs(x1-x0);
		while(nIteration > 0 && currentthreshold > threshold)
		{
			thresholdList.add(currentthreshold);
			y0 = computeY(x0);
			y1 = computeY(x1);
			x0List.add(x0);
			y0List.add(y0);
			x1List.add(x1);
			y1List.add(y1);
			x2 = ((x0*y1)-(x1*y0))/(y1-y0);
			y2 = computeY(x2);
			x2List.add(x2);
			y2List.add(y2);
			if(y2 != 0)
			{
				if (y1*y2 < 0)
				{
					x0 = x2;
					y0 = y2;
				}
				else
				{
					x1 = x2;
					y1 = y2;
				}
			}
			nIteration--;
			currentthreshold = Math.abs(x1-x0);
		}
		printEverything();
	}
	
	
	
	public void clearList(){
		x0List.clear();
		x1List.clear();
		x2List.clear();
		y0List.clear();
		y1List.clear();
		y2List.clear();
		coefList.clear();
		powerList.clear();
		trueXList.clear();
		trueYList.clear();
		thresholdList.clear();
	}
	
	public void setValues(double x0, double x1, int nIteration, String function, double threshold){
		this.x0 = x0;
		this.x1 = x1;
		this.nIteration = nIteration;
		this.threshold = threshold;
		this.parseFunction(function);
	}
	
	
	public void printEverything(){
		for(int i = 0; i < x0List.size(); i++){
		 	System.out.println("x0= " + x0List.get(i)+ " x1=" + x1List.get(i) +" y0="+ y0List.get(i)+ " y1="+y1List.get(i)+ " x2="+x2List.get(i)+ " y2="+y2List.get(i));
		 	System.out.println(thresholdList.get(i));
		}		
		//for(int i = 0; i < trueXList.size(); i++)
		//	System.out.println("x =" + trueXList.get(i) + " y =" + trueYList.get(i));
		//for(int i= 0; i < thresholdList.size(); i++)
//			System.out.println(thresholdList.get(i));
	}
	
	public ArrayList<Double> getThresholdList(){
		return thresholdList;
	}
	
	public ArrayList<Double> getTrueXList(){
		return trueXList;
	} 
	
	public ArrayList<Double> getTrueYList(){
		return trueYList;
	}
	
	public ArrayList<Double> getx0List(){
		return x0List;
	}
	
	public ArrayList<Double> getx1List(){
		return x1List;
	}
	
	public ArrayList<Double> getx2List(){
		return x2List;
	}
	
	public ArrayList<Double> gety0List(){
		return y0List;
	}
	
	public ArrayList<Double> gety1List(){
		return y1List;
	}
	
	public ArrayList<Double> gety2List(){
		return y2List;
	}
	
	public static void main(String args[])
	{
		String function = "1 2 -78.8 0";
		RegulaFalsi falsi = new RegulaFalsi(6, 12, 10, function, 2.123);
		falsi.computeRegulaFalsi();
	}
}
